﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Reflection;

namespace System
{
    [Serializable]
    public abstract class Entity : Entity<string>, IEntity
    {
        public Entity()
        {
            ID = Guid.NewGuid().ToString();
        }
    }
    [Serializable]
    public abstract class Entity<TPrimaryKey> : IEntity<TPrimaryKey>
    {
        public Entity()
        {
            OrderBy = 0;//displayorder
            AddTime = DateTime.Now;
        }
        /// <summary>
        /// 唯一标识
        /// </summary>
        [Description("唯一标识")]
        [Key]
        [Display(Name = "唯一标识")]
        public virtual TPrimaryKey ID { get; set; }
        /// <summary>
        /// 排序
        /// </summary>
        [Description("排序")]
        [Display(Name = "排序")]
        public virtual int OrderBy { get; set; }
        /// <summary>
        /// 添加时间
        /// </summary>
        [Description("添加时间")]
        [Display(Name = "添加时间")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}", ApplyFormatInEditMode = true)]
        public virtual DateTime AddTime { get; set; }
        public virtual bool IsTransient()
        {
            if (EqualityComparer<TPrimaryKey>.Default.Equals(ID, default(TPrimaryKey)))
            {
                return true;
            }
            if (typeof(TPrimaryKey) == typeof(int))
            {
                return Convert.ToInt32(ID) <= 0;
            }
            if (typeof(TPrimaryKey) == typeof(long))
            {
                return Convert.ToInt64(ID) <= 0;
            }
            return false;
        }
        public virtual bool EntityEquals(object obj)
        {
            if (obj == null || !(obj is Entity<TPrimaryKey>))
            {
                return false;
            }
            if (ReferenceEquals(this, obj))
            {
                return true;
            }
            var other = (Entity<TPrimaryKey>)obj;
            if (IsTransient() && other.IsTransient())
            {
                return false;
            }
            var typeOfThis = GetType();
            var typeOfOther = other.GetType();
            if (!typeOfThis.GetTypeInfo().IsAssignableFrom(typeOfOther) && !typeOfOther.GetTypeInfo().IsAssignableFrom(typeOfThis))
            {
                return false;
            }
            //if (this is ITenant && other is ITenant &&
            //   this.As<ITenant>().TenantId != other.As<ITenant>().TenantId)
            //{
            //    return false;
            //}
            return ID.Equals(other.ID);
        }
        public override string ToString()
        {
            return $"[{GetType().Name} {ID}]";
        }
    }
    /// <summary>
    /// 树形
    /// </summary>
    [Serializable]
    public abstract class TreeEntity : TreeEntity<string>
    {
       
    }
    /// <summary>
    /// 树形
    /// </summary>
    [Serializable]
    public abstract partial class TreeEntity<TPrimaryKey> : Entity
    {
        public TreeEntity()
        {
            
        }
        /// <summary>
        /// 名称
        /// </summary>
        [Description("名称")]
        [MaxLength(200)]
        public virtual string Name { get; set; }
        /// <summary>
        /// 上一级
        /// </summary>
        [Description("上一级")]
        [Display(Name = "上一级")]
        [MaxLength(50)]
        public TPrimaryKey ParentID { get; set; }
        /// <summary>
        /// 上一级名称
        /// </summary>
        [Description("上一级名称")]
        [MaxLength(200)]
        public virtual string ParentName { get; set; }
        //[NotMapped]
        //public List<object> Children { get; internal set; }
        //[NotMapped]
        //public int Level { get; internal set; }
    }
    public class TreeItem<T>
    {
        public T Item { get; set; }
        public IEnumerable<TreeItem<T>> Children { get; set; }
    }
}
